
<template>
    <nly-content-wrapper class="a-base-container">
        <div class="flex invoice-design" style="margin:10px;border:1px solid #ccc;height:100%;">
            <!-- 树形菜单 -->

            <div class="tree-box">
                <span style="font-size:14px">单据设计</span>
                <a-tree class="tree" show-line :tree-data="numberSetTree" @select="treeSelect" @expand="treeExpand" :expandedKeys="expandedNumberSetKeys" :selected-keys="selectedNumberSetKeys">
                    <a-icon slot="switcherIcon" type="down" />
                    <template slot="title" slot-scope="{ title }">
                        <span>{{ title }}</span>
                    </template>
                </a-tree>

            </div>
            <div class="resize-table-container ">
                <!-- 顶部搜索区域 -->
                <div style="height:52px;">
                    <a-tabs v-model="tabKey">
                        <a-tab-pane v-for="(name) in tabList" :tab="name" :key="name"></a-tab-pane>
                    </a-tabs>
                </div>
                <div class="table-page-search-wrapper btn-wrapper" style="border-bottom:none;padding:0;margin-bottom:0px;">
                    <!-- <a-form layout="inline">
                        <a-row :gutter="24" style="width:100%">
                            <a-col :md="5" :sm="8">
                                <a-form-item label="当前单据">
                                    <a-input :read-only="true" placeholder="当前单据名称" :value="selectedTitle"></a-input>
                                </a-form-item>
                            </a-col>
                            <a-col :md="6" :sm="8">
                                <a-form-item label="字段定位">
                                    <a-input @change="locate(false)" placeholder="请输入字段名称" v-model="locateText"></a-input>
                                </a-form-item>
                            </a-col>
                            <a-col :md="2" :sm="8">
                                <a-button type="primary" @click="locate(true)">定位</a-button>
                            </a-col>
                        </a-row>
                        <a-row :gutter="24" style="width:100%" v-if="!permissions.includes('NuoNiu')">
                            <a-col :md="8" :sm="8">
                                <a-button type="primary" @click="addField" style="margin-right:10px;" v-if="permissions.includes('invoiceDesign:add')">新增字段</a-button>
                                <a-button type="primary" @click="addPropertyBtn" title="引用基础档案属性" :disabled="!(tabKey == '表头' || tabKey == '明细')" v-if="permissions.includes('invoiceDesign:quote')">引用基础档案属性</a-button>
                            </a-col>
                        </a-row>
                    </a-form> -->

                    <a-row :span="8" class="text-center clearfix btn-box">
                        <a-col class="btn-item" :disabled="!(tabKey == '表头' || tabKey == '明细')" v-if="permissions.includes('invoiceDesign:save')">
                            <div class="btns" @click="SaveVoucherDesign">
                                <a-icon class="btns-icon" type="save" />
                                <div class="btns-text">保存</div>
                            </div>
                        </a-col>
                        <a-col class="btn-item" v-if="!permissions.includes('NuoNiu')">
                            <div class="btns" @click="addField">
                                <a-icon class="btns-icon" type="file-add" />
                                <div class="btns-text">新增字段</div>
                            </div>
                        </a-col>
                        <a-col class="btn-item" :disabled="!(tabKey == '表头' || tabKey == '明细')" v-if="permissions.includes('invoiceDesign:quote')">
                            <div class="btns" @click="addPropertyBtn">
                                <a-icon class="btns-icon" type="container" />
                                <!--档案-->
                                <div class="btns-text">引用基础属性</div>
                            </div>
                        </a-col>
                    </a-row>
                </div>

                <!-- 内容显示 -->
                <a-table id="voucherDesignTable" :columns="columns" :data-source="tableData" :pagination="false" :components="components" :scroll="{x:1000,y:400}" :customRow="customClick" :loading="loading" bordered>
                    <template slot="onFill" slot-scope="text, record">
                        <a-tooltip>
                            <template slot="title" v-if="!record.onEdit">
                                该字段为不可编辑字段
                            </template>
                            <template slot="title" v-else-if="record.onLocked">
                                系统锁定，无权限操作
                            </template>
                            <a-checkbox v-model="record.onFill" :disabled="!record.onOff || !record.onEdit || record.onLocked " @change="ItemEdit(record)">
                            </a-checkbox>
                        </a-tooltip>
                    </template>
                    <template slot="isSearch" slot-scope="text, record">
                        <a-checkbox v-model="record.isSearch"  @change="ItemEdit(record)">
                        </a-checkbox>
                    </template>
                    <template slot="isPrint" slot-scope="text, record">
                        <a-checkbox v-model="record.isPrint" :disabled="!record.onOff" @change="ItemEdit(record)">
                        </a-checkbox>
                    </template>

                    <a-input-number slot="columnWidth" slot-scope="text, record" v-model="record.columnWidth" :precision="0" :step="10" @change="ItemEdit(record)"></a-input-number>
                    <!-- 操作 -->
                    <span slot="operation" slot-scope="text, record, index">
                        <div v-if="!permissions.includes('NuoNiu')">
                            <a-popconfirm title="确定删除吗?" @confirm="handleDelete(record)" v-if="record.dataType > 1">
                                <a href="javascript:;" title="删除">
                                    <a-icon type="delete" :style="{ fontSize: '16px', color: '#DC3545' }" />
                                </a>
                            </a-popconfirm>
                            <a href="javascript:;" @click="moveToHead(record,index)" v-if="tabKey ==='表尾'" title="移至表头">
                                <a-icon type="swap-left" :style="{ fontSize: '16px', color: '#dd5a43' }" />
                            </a>
                            <a href="javascript:;" @click="moveToTail(record,index)" v-if="tabKey ==='表头'" title="移至表尾">
                                <a-icon type="swap-right" :style="{ fontSize: '16px', color: '#dd5a43' }" />
                            </a>
                        </div>
                        <div v-else>
                            <a-popconfirm title="确定删除吗?" @confirm="handleDelete(record)">
                                <a href="javascript:;" class="mr-2" title="删除">
                                    <a-icon type="delete" :style="{ fontSize: '16px', color: '#DC3545' }" />
                                </a>
                            </a-popconfirm>
                            <a href="javascript:;" class="mr-2" title="启用" @click="enableSystemField(record)" v-if="record.status == 2">
                                <a-icon type="stop" :style="{ fontSize: '16px', color: '#FF8534' }" />
                            </a>
                            <a href="javascript:;" class="mr-2" title="禁用" @click="disableSystemField(record)" v-if="record.status == 0">
                                <a-icon type="check-circle" :style="{ fontSize: '16px', color: '#1890ff' }" />
                            </a>
                            <a-popconfirm title="确定锁定吗?" @confirm="lockField(record)">
                                <a href="javascript:;" class="mr-2" title="锁定" v-if="!record.onLocked">
                                    <a-icon type="unlock" :style="{ fontSize: '16px', color: '#1384BD' }" />
                                </a>
                            </a-popconfirm>
                            <a-popconfirm title="确定解锁吗?" @confirm="unLockField(record)">
                                <a href="javascript:;" class="mr-2" title="解锁" v-if="record.onLocked">
                                    <a-icon type="lock" :style="{ fontSize: '16px', color: '#333' }" />
                                </a>
                            </a-popconfirm>
                            <a href="javascript:;" @click="moveToHead(record,index)" v-if="tabKey ==='表尾'" title="移至表头">
                                <a-icon type="swap-left" :style="{ fontSize: '16px', color: '#dd5a43' }" />
                            </a>
                            <a href="javascript:;" @click="moveToTail(record,index)" v-if="tabKey ==='表头'" title="移至表尾">
                                <a-icon type="swap-right" :style="{ fontSize: '16px', color: '#dd5a43' }" />
                            </a>
                        </div>

                    </span>
                    <template slot="field-type" slot-scope="text, record, index">
                        <form-select v-if=" record.columnType == '下拉'" title="下拉效果" size="small" :selectStyle="(record.onEdit && (record.dataType == 1 || record.dataType == 2)) ? ' width:80%;':' width:100%;'" labelStyle="display: none;" :dataList="valForFormFN(text)" v-model="record.value">
                            <a slot="actions" v-if="record.onEdit && (record.dataType == 1 || record.dataType == 2)" @click="editFieldContent(record,index)" style="color:#138496;font-size:1.2rem;display: inline-block;width:20%;">
                                <a-icon type="edit" theme="twoTone" title="编辑下拉框内容" />
                            </a>
                        </form-select>
                        <form-select v-if=" record.columnType == '性别'" title="下拉效果" size="small" selectStyle=" width:100%;" labelStyle="display: none;" :dataList="valForFormFN(text)" v-model="record.value">
                        </form-select>
                        <form-radio v-if="record.columnType == '单选'" title="单选效果" labelStyle="display: none;" keyPre="menuType" :dataList="valForFormFN(text)" v-model="record.value">
                            <a slot="actions" v-if="record.onEdit && (record.dataType == 1 || record.dataType == 2)" @click="editFieldContent(record,index)" style="color:#138496;font-size:1.2rem;display: inline-block;width:20%;">
                                <a-icon type="edit" theme="twoTone" title="编辑单选框内容" />
                            </a>
                        </form-radio>
                        <form-check-box v-if="record.columnType == '复选'" title="复选效果" labelStyle="display: none;" :dataList="valForCheckBoxFN(text)" v-model="record.value">
                            <a slot="actions" v-if="record.onEdit && (record.dataType == 1 || record.dataType == 2)" @click="editFieldContent(record,index)" style="color:#138496;font-size:1.2rem;display: inline-block;width:20%;">
                                <a-icon type="edit" theme="twoTone" title="编辑复选框内容" />
                            </a>
                        </form-check-box>
                        <form-radio v-if="record.columnType == '是否'" title="是否效果" labelStyle="display: none;" v-model="record.value" keyPre="menuType" :dataList="[
                  { key: '是', title: '是' },
                  { key: '否', title: '否' }
              ]"></form-radio>
                        <form-date-picker v-if="record.columnType == '日期'" title="日期效果" labelStyle="display: none;" v-model="record.value"></form-date-picker>
                        <form-date-picker v-if="record.columnType == '时间'" title="日期效果" show-time format="YYYY-MM-DD HH:mm" labelStyle="display: none;" v-model="record.value"></form-date-picker>
                        <form-input-number v-if="record.columnType == '整数'" title="整数效果" labelStyle="display: none;" :precision="0" :step="1" v-model="record.value"></form-input-number>
                        <form-input-number v-if="record.columnType == '小数'" title="小数效果" labelStyle="display: none;" :step="0.1" v-model="record.value"></form-input-number>
                    </template>
                    <!-- 搜索 -->
                    <div slot="filterDropdown" slot-scope="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }" style="padding: 8px">
                        <a-input v-ant-ref="c => (searchInput = c)" :placeholder="`搜索 ${column.title}`" :value="selectedKeys[0]" style="width: 188px; margin-bottom: 8px; display: block;" @change="e => setSelectedKeys(e.target.value ? [e.target.value] : [])" @pressEnter="() => handleSearch(selectedKeys, confirm, column.dataIndex)" />
                        <a-button type="primary" icon="search" size="small" style="width: 90px; margin-right: 8px" @click="() => handleSearch(selectedKeys, confirm, column.dataIndex)">
                            搜索
                        </a-button>
                        <a-button size="small" style="width: 90px" @click="() => handleReset(clearFilters)">
                            重置
                        </a-button>
                    </div>
                    <a-icon slot="filterIcon" slot-scope="filtered" type="search" :style="{ color: filtered ? '#108ee9' : undefined }" />
                    <template slot="customRender" slot-scope="text, record, index, column">
                        <span v-if="searchText && searchedColumn === column.dataIndex">
                            <template v-for="(fragment, i) in text.toString().split(new RegExp(`(?<=${searchText})|(?=${searchText})`, 'i'))">
                                <mark v-if="fragment.toLowerCase() === searchText.toLowerCase()" :key="i" class="highlight">{{ fragment }}</mark>
                                <template v-else>{{ fragment }}</template>
                            </template>
                        </span>
                        <template v-else>
                            {{ text }}
                        </template>
                    </template>
                    <template slot="dictCode" slot-scope="text,record">
                        <a-select v-if="record.columnType == '下拉选择' || record.columnType == '单选' || record.columnType == '复选'" allowClear option-filter-prop="children" show-search :filter-option="filterOption" @change="dictSelectChange(record)" v-model="record.dictCode" style="width:100%;border-radius:0px;">
                            <a-select-option v-for="item in dict" :key="item.dictName" :value="item.dictCode">
                                {{item.dictName}}
                            </a-select-option>
                        </a-select>
                    </template>
                </a-table>

                <!-- 右键菜单 -->
                <a-menu class="menu-style" :style="menuStyle" v-if="menuVisible">
                    <a-menu-item @click="clockMenu('head')">上移至顶部</a-menu-item>
                    <a-menu-item @click="clockMenu('headval')">
                        上移
                        <a-input type="number" v-model="headValue" :min="1" :max="99" class="menu-input" style="width:80px;"></a-input>行
                    </a-menu-item>
                    <a-menu-item @click="clockMenu('tail')">下移至尾部</a-menu-item>
                    <a-menu-item @click="clockMenu('tailval')">
                        下移
                        <a-input type="number" v-model="tailValue" :min="1" :max="99" class="menu-input" style="width:80px;"></a-input>行
                    </a-menu-item>
                </a-menu>
                <!-- 引用属性选择窗体 -->
                <a-modal v-model="propertyModalVisible" title="选择引用属性" @ok="addPropertyToDesign">
                    <a-cascader :options="propertyOptions" placeholder="请选择属性" @change="onPropertyChange" />
                </a-modal>
                <!-- 保存按钮 -->
                <!-- <div class="a-button-bar">
                    <a-button type="primary" @click="SaveVoucherDesign" v-if="permissions.includes('invoiceDesign:save')">保存</a-button>
                </div> -->
                <fieldEdit ref="fieldEdit" @ok="fieldEditOk"></fieldEdit>
                <fieldContentEdit ref="fieldContentEdit" @ok="fieldContentEditOk"></fieldContentEdit>
            </div>
        </div>
    </nly-content-wrapper>
</template>
<script>

import { mapState } from "vuex";
import { valForFormFN, valForCheckBoxFN, getOnlyCode, IdFieldToNameField } from "@/utils/customize"
import { DisAbleFirfoxDrag } from "@/utils/browser";
import { components } from "@/utils/antTableComponents";
import fieldEdit from "./model/fieldEdit";
import fieldContentEdit from "./model/fieldContentEdit";
import { list, save, deleteOne, add as addCustomField, addProperty, listDef, saveDef, enableSystemField, disableSystemField, deleteSystemField, lockField, unLockField ,listByReferenceTableCode} from "@/api/erp/voucherDesign";

import { list as listNumberSet } from "@/api/erp/mumberSet";
import { classPageListToTree, searchInTreeData } from "@/utils/tree";
import Sortable from "sortablejs";

export default {
    data () {
        const columns = [
            {
                title: "序号",
                dataIndex: "sort",
                align: 'center',
                key: "sort",
                width: 50,
                customRender: (text, record, index) => {
                    const title = "上下拖动可进行排序";
                    const style = "cursor: move;";
                    return (
                        <div title={title} style={style}>
                            {text}
                        </div>
                    );
                }
                // scopedSlots: { customRender: 'sort' },
                // customRender: (value, row, index) => `${index + 1}`
            },
            {
                title: "字段名称",
                dataIndex: "sysName",
                key: "sysName",
                width: 120,
                scopedSlots: {
                    filterDropdown: 'filterDropdown',
                    filterIcon: 'filterIcon',
                    customRender: 'customRender',
                },
                onFilter: (value, record) =>
                    record.sysName
                        .toString()
                        .toLowerCase()
                        .includes(value.toLowerCase()),
                onFilterDropdownVisibleChange: visible => {
                    if (visible) {
                        setTimeout(() => {
                            this.searchInput.focus();
                        }, 0);
                    }
                },
            },
            {
                title: "显示名称",
                dataIndex: "name",
                key: "name",
                width: 120,
                customRender: (text, record, index) => {
                    const key = "name";
                    const change = e => {
                        record[key] = e.target.value;
                        record.isEdit = true;
                    };
                    return <a-input class={'inputs' + index} value={record[key]} onChange={change}></a-input>;
                },
                scopedSlots: {
                    filterDropdown: 'filterDropdown',
                    filterIcon: 'filterIcon',
                    customRender: 'customRender',
                },
                onFilter: (value, record) =>
                    record.name
                        .toString()
                        .toLowerCase()
                        .includes(value.toLowerCase()),
                onFilterDropdownVisibleChange: visible => {
                    if (visible) {
                        setTimeout(() => {
                            this.searchInput.focus();
                        }, 0);
                    }
                },
            },
            {
                title: "字段CODE",
                dataIndex: "code",
                key: "code",
                width: 120,
                customRender: (text, record, index) => {
                    if (this.permissions.includes('NuoNiu')) {
                        const key = "code";
                        const change = e => {
                            record[key] = e.target.value;
                            record.isEdit = true;
                        };
                        return <a-input class={'inputs' + index} value={record[key]} onChange={change}></a-input>;
                    } else {
                        return text;
                    }

                },
            },
            {
                title: "数据类型",
                dataIndex: "dataType",
                key: "dataType",
                width: 100,
                customRender: (text, row, index) => {
                    let heml = null;
                    switch (text) {
                        case 1: heml = <div>系统字段</div>; break;
                        case 2: heml = <div>自定义</div>; break;
                        case 3: heml = <div>引用属性</div>; break;
                        case 4: heml = <div>引用自定义属性</div>; break;
                    }
                    return heml;
                }
            },
            {
                title: "字段类型",
                dataIndex: "columnType",
                key: "columnType",
                width: 80,
            },
            {
                title: "对应字典",
                dataIndex: "dictCode",
                key: "dictCode",
                width: 120,
                scopedSlots: { customRender: "dictCode" }
            },
            {
                title: "字段内容",
                dataIndex: "val",
                key: "val",
                width: 120,
                align: "left",
                scopedSlots: { customRender: "field-type" }
            },
            {
                title: "列宽",
                dataIndex: "columnWidth",
                width: 60,
                key: "columnWidth",
                scopedSlots: { customRender: 'columnWidth' },
            },
            {
                title: "启用",
                dataIndex: "onOff",
                key: "onOff",
                align: "center",
                width: 80,
                customRender: (text, record) => {
                    const key = "onOff";
                    const change = e => {
                        let checked = e.target.checked;
                        if (!checked) {
                            record.onFill = false;
                            record.isSearch = false;
                        }
                        record[key] = checked;
                        record.isEdit = true;
                    };
                    return (
                        <a-checkbox checked={record[key]} disabled={record.onLocked} onChange={change} ></a-checkbox>
                    );
                }
            },
            {
                title: "必填",
                dataIndex: "onFill",
                key: "onFill",
                align: "center",
                width: 80,
                scopedSlots: { customRender: "onFill" }
                // customRender: (text, record) => {
                //   const key = "onFill";
                //   const change = e => {
                //     record[key] = e.target.checked;
                //     record.isEdit = true;
                //   };
                //   return (
                //     <a-checkbox checked={record[key]} disabled={record.onLocked} onChange={change}></a-checkbox>
                //   );
                // }
            },
            {
                title: "搜索条件",
                dataIndex: "isSearch",
                key: "isSearch",
                align: "center",
                width: 80,
                scopedSlots: { customRender: "isSearch" }
                // customRender: (text, record) => {
                //   const key = "isSearch";
                //   const change = e => {
                //     record[key] = e.target.checked;
                //     record.isEdit = true;
                //   };
                //   return (
                //     <a-checkbox checked={record[key]} disabled={record.onLocked} onChange={change}></a-checkbox>
                //   );
                // }
            },
            {
                title: "是否打印",
                dataIndex: "isPrint",
                key: "isPrint",
                align: "center",
                width: 80,
                scopedSlots: { customRender: "isPrint" }
            },
            {
                title: "操作",
                dataIndex: "operation",
                key: "operation",
                align: "center",
                width: 100,
                scopedSlots: { customRender: "operation" }
            }
        ];
        //表格 头部 可伸缩
        this.components = components(columns);
        return {
            valForFormFN,
            valForCheckBoxFN,
            getOnlyCode,
            IdFieldToNameField,
            searchName: "", //tree搜索名称
            //定位的输入
            locateText: '',
            //定位的下标
            locateIndex: -1,
            //单选多选样式
            radioBoxStyle: {
                display: "block",
                height: "30px",
                lineHeight: "30px"
            },
            //表格加载状态
            loading: false,
            //
            tabKey: '表头',
            // //标签列表
            // tabList: ["表头", "明细", "汇总", "表尾"],
            //搜索文本
            searchText: '',
            //搜索输入框
            searchInput: null,
            //搜索结果
            searchedColumn: '',
            //当前编辑的数据下标
            editIndex: 0,
            //某个单据 表单设计 集合数据
            designList: [],
            //某个单据 表单设计 tab分类 Map
            designTabMap: new Map(),
            //表格数据
            data: [],
            //表头信息
            columns,
            //表格默认大小设置（滚动条）
            scroll: { x: 500, y: 600 },
            //调用地址
            url: {
                list: [],
                delete: [],
                update: []
            },

            //右键菜单是否显示
            menuVisible: false,
            //右键菜单样式
            menuStyle: {
                boxShadow: "2px 2px 3px #888888",
                position: "fixed",
                top: "0",
                left: "0",
                border: "1px solid #eee"
            },
            //右键窗口是否关闭
            closeFlag: false,
            // 绑定右击事件
            customClick: (record, index) => ({
                on: {
                    contextmenu: e => {
                        e.preventDefault();
                        console.log(index);
                        this.editIndex = index;
                        this.menuVisible = true;

                        this.menuStyle.top = e.clientY + "px";
                        //当点击位置靠下时，修改定位点
                        if (window.innerHeight - 300 < e.clientY) {
                            this.menuStyle.top = e.clientY - 190 + "px"
                        }
                        this.menuStyle.left = e.clientX + 5 + "px";
                        console.log(e.clientY)
                        console.log(window.innerHeight)
                        document.body.addEventListener("mousedown", this.onMouseDown);
                    }
                }
            }),
            //上移单位数量
            headValue: 1,
            //下移单位数量
            tailValue: 1,
            //新增、编辑字段弹窗是否显示
            modalVisible: false,
            //模态框title
            modelTitle: "编辑自定义字段", // '新增自定义字段'
            propertyModalVisible: false,  //引用属性选择窗体是否显示

            selectPropertyId: null,       //引用属性 ID
            propertyTabMap: new Map(),     //引用属性 
            propertyMap: new Map(),
            //字段类型列表
            fieldTypeList: [
                { key: "文本", title: "文本" },
                { key: "下拉", title: "下拉" },
                { key: "复选", title: "复选" },
                { key: "单选", title: "单选" },
                { key: "日期", title: "日期" },
                { key: "时间", title: "时间" },
                { key: "整数", title: "整数" },
                { key: "小数", title: "小数" },
                { key: "是否", title: "是否" },
                { key: "区块", title: "区块" }
            ],
            selectedNumberSetKeys: [],         //选择的项
            expandedNumberSetKeys: [],         //展开的项
            selectedTitle: "",
            numberSetList: [],
            numberSetTree: [],
            
            //单据请求参数
            postData: {
                source: "PurchaseRequisition",
            },
            dict: JSON.parse(localStorage.getItem('dict'))
        };
    },
    components: {
        fieldEdit,
        fieldContentEdit
    },
    created () {
        this.listNumberSet();
        console.log('字典：', this.dict);
    },
    mounted () {
        DisAbleFirfoxDrag();
        this.LoadData();
    },
    computed: {
        //引用属性 选择数据源
        propertyOptions: function () {
            const { propertyMap,propertyTabMap, tabKey } = this;
            propertyMap.clear();
            console.log("计算后的引用属性：", propertyTabMap);
            let list = propertyTabMap.get(tabKey) || [];
            let map = new Map();
            list.forEach(item => {
                let { name, code, dataTab, dataType, referenceTableCode,voucherField } = item;
                let referenceTableName = "物料";
                switch(referenceTableCode){
                    case "Inventory":referenceTableName = "物料";break;
                    case "Project":referenceTableName = "项目";break;
                }
                let childrenKey = referenceTableCode + "_"+ code;
                propertyMap.set(childrenKey,item);
                let key = referenceTableCode;
                let firstLevel = map.get(key);
                if (!firstLevel) {
                    firstLevel = new Object();
                    firstLevel.label = referenceTableName;
                    firstLevel.value = referenceTableCode;
                    firstLevel.children = [];
                    map.set(key, firstLevel);
                }
                firstLevel.children.push({
                    label: name,
                    value: childrenKey
                });

            });
            let options = [...map.values()];
            console.log("...引用属性 选择数据源", options);
            return options;
        },
        tabList: function () {
            const { designTabMap } = this;
            let keys = [...designTabMap.keys()];

            console.log("计算后的tabKeys：", keys);
            //排序
            if (keys.indexOf("表头") > -1) {
                keys.sort(function (a, b) { return (a === '表尾' || b === "表头") ? 1 : -1 });
            }
            return keys;
        },
        tableData: function () {
            const { designTabMap, tabKey } = this;
            let dataList = designTabMap.get(tabKey) || [];
            return dataList;
        },
        //选择单据的名称
        selectedInvoiceName: function () {
            // console.log("AntMenu_this.$route",this.$route);
            return [this.$route.meta.title || "未选择单据"];
        },
        //选择单据的id（目前是页面的id）
        selectedInvoiceId: function () {
            // console.log("AntMenu_this.$route",this.$route);
            return [this.$route.meta.id || ""];
        },
        ...mapState({
            permissions: state => state.user.permissions,
        }),
    },
    watch: {
        $route: {
            handler: function (to, from) {
                console.log('路由发生变化_invoiceDesign');
                //from 对象中包含当前地址
                //to 对象中包含目标地址
                //其实还有一个next参数的，这个参数是控制路由是否跳转的，如果没写，可以不用写next()来代表允许路由跳转，如果写了就必须写next(),否则路由是不会生效的。
                DisAbleFirfoxDrag();
                this.LoadData();
                this.listNumberSet();
            }
        }
    },
    // activated () {
    //     this.listNumberSet();
    // },
    methods: {
        dictSelectChange (row) {
            row.isEdit = true;
        },
        filterOption (input, option) {
            return (
                option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
            );
        },
        //重新加载 单据数据
        reloadData () {
            this.list();
            this.listByReferenceTableCode();
        },
        //该对象是否更改过
        ItemEdit (row) {
            console.log("ItemEdit_row", row)
            row.isEdit = true;
        },
        //tree 搜索
        // treeSearch() {
        //   const value = this.searchName;
        //   console.log(value);
        //   const keys = [];
        //   const treeData = searchInTreeData(keys, this.treeData, "title", value);
        //   console.log(keys.length);
        //   if (keys.length < 1) {
        //     this.expandedKeys = [...groupMap.keys()];
        //     this.autoExpandParent = false;
        //   } else {
        //     this.expandedKeys = keys;
        //     this.autoExpandParent = true;
        //   }
        // },

        //选择树
        treeSelect (selectedKeys, info) {
            console.log(selectedKeys[0]);
            if (selectedKeys.length > 0) {
                const currentKey = selectedKeys[0];
                if (currentKey.startsWith("N_")) {
                    return false;
                }
                const { node } = info;
                const selectedTitle = node._props.title;
                Object.assign(this, { selectedTitle });
                this.selectedNumberSetKeys = selectedKeys;
                this.postData.source = selectedKeys[0];
                this.reloadData();
            }
        },
        treeExpand (expandedKeys) {
            console.log("展开的节点1：", this.expandedNumberSetKeys);
            this.expandedNumberSetKeys = expandedKeys;
            console.log("展开的节点：", expandedKeys);
        },
        //加载 单据编码
        listNumberSet () {
            //FV：财务 MP：生产 PU：采购 SA：销售 ST：库存
            let type = this.$route.path.split('/')[4];
            let request = {};
            if (type) {
                request = { moduleCodes: type.split(',') }
            }
            listNumberSet(request).then(response => {
                if (response.code === 200) {
                    const { data } = response;
                    let map = new Map();
                    data.forEach(item => {
                        let { moduleName, voucherCode, name } = item;
                        let firstLevel = map.get(moduleName);
                        if (!firstLevel) {
                            firstLevel = new Object();
                            firstLevel.title = moduleName;
                            firstLevel.key = "N_" + moduleName;
                            firstLevel.children = [];
                            map.set(moduleName, firstLevel);
                        }
                        firstLevel.children.push({
                            key: voucherCode,
                            title: name
                        });

                    });
                    this.numberSetTree = [...map.values()];
                    console.log(this.numberSetTree)
                    if (type == 'CM') {
                        this.numberSetTree = [
                            {
                                "title": "合同管理",
                                "key": "N_合同管理",
                                "children": [
                                    {
                                        "key": "Contract",
                                        "title": "合同单据"
                                    },
                                ]
                            }
                        ];
                    }
                    if (data.length > 0) {
                        const firstParent = this.numberSetTree[0];
                        const parentKey = firstParent.key;
                        const firstItem = firstParent.children[0];

                        console.log("加载第一个对象.....", firstItem);
                        const { key, title } = firstItem;
                        this.selectedTitle = title;
                        this.selectedNumberSetKeys = [key];
                        this.expandedNumberSetKeys = [parentKey];
                        console.log("展开、选择的keys:", this.expandedNumberSetKeys, this.selectedNumberSetKeys);
                        this.postData.source = key;
                        //加载
                        this.reloadData();
                    }
                }
            }).catch(error => { });
        },
        //
        addPropertyBtn () {
            this.propertyModalVisible = true;
        },
        // 加载 引用属性
        listByReferenceTableCode () {
            const { postData } = this;
            listByReferenceTableCode(postData)
                .then(response => {
                    if (response.code === 200) {
                        const { data } = response;
                        const map = new Map();
                        data.forEach(item => {
                            if(item.dataType && item.dataType > 2)return;
                            let list = map.get(item.dataTab);
                            if (!list) {
                                list = new Array();
                                map.set(item.dataTab, list);
                            }
                            list.push(item);
                        });
                        this.propertyTabMap = map;
                        console.log("引用属性查询结果：",map);
                    }
                })
                .catch(error => { });
        },
        //引用属性
        onPropertyChange (val) {
            if (val.length > 0) {
                this.selectPropertyId = val[val.length - 1];
            } else {
                this.selectPropertyId = null;
            }
        },
        //保存 引用属性 到单据设计
        addPropertyToDesign () {
            const { propertyMap,selectPropertyId } = this;
            if (!selectPropertyId) {
                this.$message.warning("请选择引用属性");
                return false;
            }
            let item =  propertyMap.get(selectPropertyId);
            addProperty(item)
                .then(response => {
                    if (response.code === 200) {
                        this.$message.success("保存成功");
                        this.propertyModalVisible = false;
                        this.reloadData();
                    } else {
                        this.$message.error(response.message);
                    }
                }).catch(error => { });
        },
        //移动至表头
        moveToHead (record, oldIndex) {
            const { tableData, designTabMap } = this;
            const removeItem = tableData.splice(oldIndex, 1)[0];
            const headList = designTabMap.get("表头");
            headList.push(removeItem);
            removeItem.dataTab = "表头";
            headList.forEach((item, index) => {
                item.sort = index + 1;
                item.isEdit = true;
            });
            tableData.forEach((item, index) => {
                item.sort = index + 1;
                item.isEdit = true;
            });
            this.renderTab();
        },
        //移动至表尾
        moveToTail (record, oldIndex) {
            const { tableData, designTabMap } = this;
            const removeItem = tableData.splice(oldIndex, 1)[0];
            const tailList = designTabMap.get("表尾");
            tailList.push(removeItem);
            removeItem.dataTab = "表尾";
            tailList.forEach((item, index) => {
                item.sort = index + 1;
                item.isEdit = true;
            });
            tableData.forEach((item, index) => {
                item.sort = index + 1;
                item.isEdit = true;
            });
            this.renderTab();
        },

        //锁定 字段
        lockField (record) {
            lockField(record).then(response => {
                if (response.code == 200) {
                    this.$message.success("锁定成功");
                    this.list();
                }
            }).catch(err => { });

        },
        //解锁 字段
        unLockField (record) {
            const { id } = record;
            unLockField({ id }).then(response => {
                if (response.code == 200) {
                    this.$message.success("解锁成功");
                    this.list();
                }
            }).catch(err => { });

        },
        //启用 字段
        enableSystemField (record) {
            const { id } = record;
            enableSystemField({ id }).then(response => {
                if (response.code == 200) {
                    this.$message.success("启用成功");
                    this.list();
                }
            }).catch(err => { });

        },
        //禁用 字段
        disableSystemField (record) {
            const { id } = record;
            disableSystemField({ id }).then(response => {
                if (response.code == 200) {
                    this.$message.success("禁用成功");
                    this.list();
                }
            }).catch(err => { });

        },
        //删除 
        handleDelete (record) {
            const { permissions } = this;
            const { id } = record;
            let deleteAction = deleteOne;
            if (permissions.includes('NuoNiu')) {
                deleteAction = deleteSystemField;
            }
            deleteAction({ id }).then(response => {
                if (response.code == 200) {
                    this.$message.success("删除成功");
                    this.list();
                }
            }).catch(err => { })
        },
        //批量保存 单据设计数据
        SaveVoucherDesign () {
            const { designList, permissions } = this;
            let filter = designList.filter(f => f.isEdit);
            if (!filter.length) {
                this.$message.error("当前页面没有修改");
                return false;
            }
            let saveAction = save;
            if (permissions.includes('NuoNiu')) {
                saveAction = saveDef;
            }
            saveAction(filter).then(response => {
                if (response.code == 200) {
                    this.$message.success("保存成功");
                    this.reloadData();
                } else {
                    this.$message.error(response.message);
                }
            }).catch(error => { });
        },
        //tab分类Map
        changeToTabMap () {
            const { designList } = this;
            let designTabMap = new Map();

            designList.forEach(item => {
                let list = designTabMap.get(item.dataTab);
                if (!list) {
                    list = new Array();
                    designTabMap.set(item.dataTab, list);
                }
                list.push(item);
            });
            console.log("tab分类Map", designTabMap);
            let keys = [...designTabMap.keys()];
            if (keys.length > 0) {
                if (!keys.includes(this.tabKey)) {
                    if (keys.indexOf("表头") > -1) {
                        this.tabKey = "表头";
                    } else {
                        this.tabKey = keys[0];
                    }
                }
                console.log("重新加载单据：初始化tabKey：", this.tabKey);
            }
            Object.assign(this, { designTabMap });

        },
        //获取 某个单据的单据设计 数据
        list () {
            const { postData, permissions } = this;
            let listAction = list;
            if (permissions.includes('NuoNiu')) {
                listAction = listDef;
            }
            listAction(postData)
                .then(response => {
                    if (response.code === 200) {
                        const { data } = response;
                        this.designList = data;
                        this.changeToTabMap();
                    }
                })
                .catch(error => { });
        },
        //定位字段
        locate (searchFlag) {
            //如果是输入框变更，设置查询定位下标为-1
            if (!searchFlag) {
                this.locateIndex = -1;
                return;
            }
            this.$nextTick(() => {
                var index = this.locateIndex === -1 ? 0 : this.locateIndex + 1;
                let flag = false;
                for (index; index < this.tableData.length; index++) {
                    if (this.tableData[index].sysName.indexOf(this.locateText) !== -1) {
                        flag = true;
                        // this.locateIndex = index;
                        break;
                    }
                }
                if (flag) {
                    this.locateIndex = index;
                    document.getElementsByClassName("inputs" + this.locateIndex)[0].focus();
                    console.log(this.locateIndex);
                } else {
                    if (this.locateIndex !== -1) {
                        this.locateIndex = -1;
                        this.locate(true);
                    } else {
                        console.log('没有哦');
                    }

                }
            })
        },
        //字段类型变更时
        fieldTypeChange (index) {
            const type = this.data[index].type;
            //如果从非下拉、复选、单选，变更成下拉、复选、单选
            //需要初始化listData（字段内容）
            if ("下拉复选单选".indexOf(type) !== -1
                && this.data[index].listData === undefined) {
                this.data[index].listData = [];
            }
        },
        //编辑字段内容回调
        fieldContentEditOk (listData) {
            console.log("编辑字段内容回调", listData)
            this.tableData[this.editIndex].val = listData.join(",");
            this.tableData[this.editIndex].isEdit = true;
            //TODO 保存更新
        },
        //编辑字段内容
        editFieldContent (record, index) {
            this.editIndex = index;
            this.$refs.fieldContentEdit.edit(record.val ? record.val.split(",") : []);
            this.$refs.fieldContentEdit.title = "编辑字段内容";
        },
        //自定义 字段 添加成功后的回调
        fieldEditOk () {
            this.reloadData();
        },
        //添加字段
        addField () {
            const { source } = this.postData;
            const { tabKey } = this;
            let props = {
                title: "新增字段",
                source,
                dataTab: tabKey
            }
            Object.assign(this.$refs.fieldEdit, { ...props });
            this.$refs.fieldEdit.add();
        },
        moveTabelNode (target) {
            //取出当前操作节点
            const node = this.tableData.splice(this.editIndex, 1)[0];
            console.log(node)
            // 放到第一个
            if (target < 0) {
                target = 0;
            }
            if (target > this.tableData.length) {
                target = this.tableData.length;
            }
            console.log(target);
            this.tableData.splice(target, 0, node);
            this.menuVisible = false;
            this.tableData.forEach((item, index) => {
                item.sort = index + 1;
                item.isEdit = true;
            });
            this.renderTab();
            document.body.removeEventListener("mousedown", this.onMouseDown);
        },
        //刷新Tab里面的表格数据
        renderTab () {
            let oldTabKey = this.tabKey;
            this.tabKey = '';
            this.$nextTick(function () {
                this.tabKey = oldTabKey;
            })
        },
        //点击右键小菜单
        clockMenu (type) {
            console.log(this.closeFlag);
            if (!this.closeFlag) {
                return;
            }
            if (type === 'head') {
                this.moveTabelNode(0);
                return;
            }
            if (type === 'tail') {
                this.moveTabelNode(this.tableData.length - 1);
                return;
            }
            if (type === 'headval') {
                this.moveTabelNode(this.editIndex - this.headValue);
                this.headValue = 1;
                return;
            }
            if (type === 'tailval') {
                this.moveTabelNode(this.editIndex + this.tailValue);
                this.tailValue = 1;
                return;
            }

        },
        //点击鼠标时，移出右键显示的菜单
        onMouseDown (event) {
            var e = event || window.event;
            var elem = e.target;
            //获取自定义菜单区域
            var targetArea = document.getElementsByClassName("menu-style")[0];
            if (targetArea.contains(elem)) {
                // 在区域内
                //判断电机的是不是input框
                var inputArea = document.getElementsByClassName("menu-input");
                if (!inputArea[0].contains(elem) && !inputArea[1].contains(elem)) {
                    this.closeFlag = true;
                } else {
                    this.closeFlag = false;
                }
            } else {
                //在区域外时，结束右击事件
                this.menuVisible = false;
                document.body.removeEventListener("mousedown", this.onMouseDown);
            }
        },
        //加载数据
        LoadData () {
            this.drag();
            // let queryParam = {};
            // this.loading = true;
            // getAction(this.url.list, queryParam).then(res => {
            //   if (res.success) {
            //     this.data = res.result.records;
            //     //添加拖动效果
            //     this.drag();
            //   } else {
            //     // this.$message.warning(res.message);
            //   }
            //   this.loading = false;
            // });
        },
        //标签切换调用
        tabChange (key) {
            console.log(key);
            this.tabKey = key;
        },
        //搜索
        handleSearch (selectedKeys, confirm, dataIndex) {
            confirm();
            this.searchText = selectedKeys[0];
            this.searchedColumn = dataIndex;
        },
        //搜索重置
        handleReset (clearFilters) {
            clearFilters();
            this.searchText = '';
        },
        // 拖动
        drag () {
            // 首先获取需要拖拽的dom节点
            const el1 = document.querySelectorAll(
                "#voucherDesignTable .ant-table-tbody"
            )[0];
            if (!el1) return false;
            this.isDrag = true;
            console.log("初始化拖动：", el1);
            Sortable.create(el1, {
                disabled: false, // 是否开启拖拽
                ghostClass: "sortable-ghost", //拖拽样式
                animation: 150, // 拖拽延时，效果更好看
                group: {
                    // 是否开启跨表拖拽
                    pull: false,
                    put: false
                },
                onEnd: e => {
                    // 这里主要进行数据的处理，拖拽实际并不会改变绑定数据的顺序，这里需要自己做数据的顺序更改
                    let arr = this.tableData; // 获取表数据
                    let removeItem = arr.splice(e.oldIndex, 1)[0];
                    arr.splice(e.newIndex, 0, removeItem); // 数据处理
                    //提前 赋值一个带值的数组（BUG 修复）

                    arr.forEach((item, index) => {
                        item.sort = index + 1;
                        item.isEdit = true;
                    });
                    let oldTabKey = this.tabKey;
                    this.tabKey = '';
                    this.$nextTick(function () {
                        this.tabKey = oldTabKey;
                    })
                }
            });
        }
    }
};
</script>
<style lang="less" scoped>
    @import '~@/style/setting/btn.less';
    .invoice-design {
        .tree-box {
            width: 200px;
            border-right: 1px solid #ccc;
            height: 100%;
            overflow-y: auto;
            padding: 10px;
            .flex {
                align-items: center;
                margin: 5px 0px 10px;
            }
            .title {
                text-align: center;
                font-size: 18px;
            }
            button {
                margin-left: 10px;
            }
        }
    }

    .resize-table-container {
        width: calc(100% - 210px);
        padding: 10px;
        position: relative;
    }
    .menu-style {
        padding: 5px;
        width: 200px;
    }
    .ant-menu-item:hover {
        background-color: rgb(236, 236, 236) !important;
    }
    .ant-checkbox-group,
    .ant-radio-group {
        display: flex;
        flex-wrap: wrap;
    }
    .ant-checkbox-wrapper,
    .ant-radio-wrapper {
        margin-left: 0px;
        margin-right: 8px;
        font-size: 13px;
    }
    .w100pencent {
        width: 100%;
    }
    .w100pencent-30 {
        width: calc(100% - 30px);
    }

    #voucherDesignTable {
        .ant-select-selection,
        .ant-input,
        .ant-input-number {
            border: 0px solid #ccc;
        }
    }

    .table-page-search-wrapper {
        position: absolute;
        right: 0px;
        z-index: 100;
        width: 300px;
        .btn-box {
            display: flex;
            .btn-item {
                flex: 1;
                width: 20%;
            }
        }
    }
</style>
 